#include <stdio.h>

int main(int argc, char const *argv[]) {
    for (int i = 0; i < argc; i++) {
        printf("%d: %s\n", i, argv[i]);
    }

    // 字符串
    char *str = "Hello";
    char str2[] = "Hello";
    char str3[10] = "Hello";

    // 字符串自动连接
    printf("%s, %s, "
            "%s\n", str, str2, str3);

    char *str11 = "Hello";
    char *str12 = "Hello";
    char str13[] = "Hello";
    char str14[] = "Hello";

    // str11, str12 是一个指针，初始化为指向一个字符串常量, 是只读的
    // 实际上是 const char *str 的写法，由于历史原因，编译器接受不带 const 的写法
    // str[0] = 'h' 试图对 str 所指的字符串做写入会导致严重的后果
    // 如果需要修改字符串，应该用数组的方式定义 char str[] = "Hello";
    printf("str11 = %p\n", str11); //str11 = 0x5566fe810004
    printf("str12 = %p\n", str12); //str12 = 0x5566fe810004
    printf("str13 = %p\n", str13); //str13 = 0x7fffb7d7be82
    printf("str14 = %p\n", str14); //str14 = 0x7fffb7d7be88
    
    char *str21 = "Hello";
    char *str22;
    printf("str22 = %p\n", str22); //str22 = (nil)

    str22 = str21;
    printf("str21 = %p\n", str11); //str21 = 0x557c276c6004
    printf("str22 = %p\n", str12); //str22 = 0x557c276c6004
    // 并没有产生新的字符串，只是让指针 str22 指向了 str21 所指的字符串
    // 对 str22 的任何操作就是对 str21 做的
    
    char str31[8];
    // scanf 读入一个单词(到空格、tab 或回车为止)
    // scanf 是不安全的，因为不知道要读入内容的长度
    // 输入单词超过变量声明长度，运行会出错
    // scanf("%s", &str31);
    // 在 % 后跟上数字，表示最多允许读入的字符数，这个数字最大值应该比数组的大小小1
    scanf("%7s", &str31);
    printf("%s\n", str31);

    char str41[100] = "";  // 这是一个空的字符串
    char str42[] = "";  // 这个数组的长度只有1, 放不下任何字符串

    // 字符串数组
    char *s[] = {};


    int ch;
    // Ctrl+C 是强制结束程序
    // Ctrl+D 才是真正的 EOF 信号，Windows 下是 Ctrl+Z
    // 注：为什么实际执行时看到的是按了回车之后才开始输出？
    // 其实是因为shell的包装，当按下回车时，shell 才开始把用户输入依次送给程序
    while ((ch = getchar()) != EOF) {
        putchar(ch);
        printf("#");
    }

    return 0;
}
